bitkeeper revision 1.1159.170.29 (419a0009K2EoexbNZXY_leDTaivx2w)
authorkaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk>
Tue, 16 Nov 2004 13:26:33 +0000 (13:26 +0000)
committerkaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk>
Tue, 16 Nov 2004 13:26:33 +0000 (13:26 +0000)
Fix make_page_{readonly,writable} to deal properly with highmem.

linux-2.6.9-xen-sparse/arch/xen/i386/kernel/traps.c
linux-2.6.9-xen-sparse/arch/xen/i386/mm/pgtable.c
linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/pgalloc.h
linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/pgtable.h

index dd1c42b8400a1acb7e32927e58505dc6e96fbd6a..dd14a5bc5888754443ba52d9acb89efa067b5740 100644 (file)
@@ -1064,7 +1064,7 @@ void __init trap_init(void)
        clear_page(&default_ldt[0]);
        set_call_gate(&default_ldt[0],lcall7);
        set_call_gate(&default_ldt[4],lcall27);
-       __make_page_readonly(&default_ldt[0]);
+       make_lowmem_page_readonly(&default_ldt[0]);
        xen_flush_page_update_queue();
 
        /*
index 4516df164330ddafe8b575c04459120da28ad64e..791c6ce3f8d2f1c051a5a0216fe7b59d09b736dc 100644 (file)
@@ -179,7 +179,7 @@ pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
        pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
        if (pte) {
                clear_page(pte);
-               __make_page_readonly(pte);
+               make_page_readonly(pte);
                xen_flush_page_update_queue();
        }
        return pte;
@@ -192,7 +192,7 @@ void pte_ctor(void *pte, kmem_cache_t *cache, unsigned long unused)
        set_page_count(page, 1);
 
        clear_page(pte);
-       __make_page_readonly(pte);
+       make_page_readonly(pte);
        queue_pte_pin(virt_to_phys(pte));
        flush_page_update_queue();
 }
@@ -203,7 +203,7 @@ void pte_dtor(void *pte, kmem_cache_t *cache, unsigned long unused)
        ClearPageForeign(page);
 
        queue_pte_unpin(virt_to_phys(pte));
-       __make_page_writable(pte);
+       make_page_writable(pte);
        flush_page_update_queue();
 }
 
@@ -304,7 +304,7 @@ void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused)
        spin_unlock_irqrestore(&pgd_lock, flags);
        memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t));
  out:
-       __make_page_readonly(pgd);
+       make_page_readonly(pgd);
        queue_pgd_pin(__pa(pgd));
        flush_page_update_queue();
 }
@@ -315,7 +315,7 @@ void pgd_dtor(void *pgd, kmem_cache_t *cache, unsigned long unused)
        unsigned long flags; /* can be called from interrupt context */
 
        queue_pgd_unpin(__pa(pgd));
-       __make_page_writable(pgd);
+       make_page_writable(pgd);
        flush_page_update_queue();
 
        if (PTRS_PER_PMD > 1)
@@ -360,3 +360,71 @@ void pgd_free(pgd_t *pgd)
        /* in the non-PAE case, clear_page_tables() clears user pgd entries */
        kmem_cache_free(pgd_cache, pgd);
 }
+
+void make_lowmem_page_readonly(void *va)
+{
+       pgd_t *pgd = pgd_offset_k((unsigned long)va);
+       pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
+       pte_t *pte = pte_offset_kernel(pmd, (unsigned long)va);
+       queue_l1_entry_update(pte, (*(unsigned long *)pte)&~_PAGE_RW);
+}
+
+void make_lowmem_page_writable(void *va)
+{
+       pgd_t *pgd = pgd_offset_k((unsigned long)va);
+       pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
+       pte_t *pte = pte_offset_kernel(pmd, (unsigned long)va);
+       queue_l1_entry_update(pte, (*(unsigned long *)pte)|_PAGE_RW);
+}
+
+void make_page_readonly(void *va)
+{
+       pgd_t *pgd = pgd_offset_k((unsigned long)va);
+       pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
+       pte_t *pte = pte_offset_kernel(pmd, (unsigned long)va);
+       queue_l1_entry_update(pte, (*(unsigned long *)pte)&~_PAGE_RW);
+       if ( (unsigned long)va >= (unsigned long)high_memory )
+       {
+               unsigned long phys;
+               phys = machine_to_phys(*(unsigned long *)pte & PAGE_MASK);
+#ifdef CONFIG_HIGHMEM
+               if ( (phys >> PAGE_SHIFT) < highstart_pfn )
+#endif
+                       make_lowmem_page_readonly(phys_to_virt(phys));
+       }
+}
+
+void make_page_writable(void *va)
+{
+       pgd_t *pgd = pgd_offset_k((unsigned long)va);
+       pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
+       pte_t *pte = pte_offset_kernel(pmd, (unsigned long)va);
+       queue_l1_entry_update(pte, (*(unsigned long *)pte)|_PAGE_RW);
+       if ( (unsigned long)va >= (unsigned long)high_memory )
+       {
+               unsigned long phys;
+               phys = machine_to_phys(*(unsigned long *)pte & PAGE_MASK);
+#ifdef CONFIG_HIGHMEM
+               if ( (phys >> PAGE_SHIFT) < highstart_pfn )
+#endif
+                       make_lowmem_page_writable(phys_to_virt(phys));
+       }
+}
+
+void make_pages_readonly(void *va, unsigned int nr)
+{
+       while ( nr-- != 0 )
+       {
+               make_page_readonly(va);
+               va = (void *)((unsigned long)va + PAGE_SIZE);
+       }
+}
+
+void make_pages_writable(void *va, unsigned int nr)
+{
+       while ( nr-- != 0 )
+       {
+               make_page_writable(va);
+               va = (void *)((unsigned long)va + PAGE_SIZE);
+       }
+}
index 77d16e3e72fb18e55e6099ad09eb5ddefe8598c8..c98a6d29335a85706100a34cee33b43eeb86effa 100644 (file)
@@ -32,7 +32,7 @@ extern struct page *pte_alloc_one(struct mm_struct *, unsigned long);
 static inline void pte_free_kernel(pte_t *pte)
 {
        free_page((unsigned long)pte);
-       __make_page_writable(pte);
+       make_page_writable(pte);
        flush_page_update_queue();
 }
 
index 67325a02624763060a59a666f704422b770afab3..cb5c4bb372a01f15d79d0901ef9a56c9c3040b36 100644 (file)
@@ -465,61 +465,12 @@ do {                                                                      \
 } while (0)
 
 /* NOTE: make_page* callers must call flush_page_update_queue() */
-static inline void __make_page_readonly(void *va)
-{
-       pgd_t *pgd = pgd_offset_k((unsigned long)va);
-       pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
-       pte_t *pte = pte_offset_kernel(pmd, (unsigned long)va);
-       queue_l1_entry_update(pte, (*(unsigned long *)pte)&~_PAGE_RW);
-}
-
-static inline void __make_page_writable(void *va)
-{
-       pgd_t *pgd = pgd_offset_k((unsigned long)va);
-       pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
-       pte_t *pte = pte_offset_kernel(pmd, (unsigned long)va);
-       queue_l1_entry_update(pte, (*(unsigned long *)pte)|_PAGE_RW);
-}
-
-static inline void make_page_readonly(void *va)
-{
-       pgd_t *pgd = pgd_offset_k((unsigned long)va);
-       pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
-       pte_t *pte = pte_offset_kernel(pmd, (unsigned long)va);
-       queue_l1_entry_update(pte, (*(unsigned long *)pte)&~_PAGE_RW);
-       if ( (unsigned long)va >= VMALLOC_START )
-               __make_page_readonly(machine_to_virt(
-                       *(unsigned long *)pte&PAGE_MASK));
-}
-
-static inline void make_page_writable(void *va)
-{
-       pgd_t *pgd = pgd_offset_k((unsigned long)va);
-       pmd_t *pmd = pmd_offset(pgd, (unsigned long)va);
-       pte_t *pte = pte_offset_kernel(pmd, (unsigned long)va);
-       queue_l1_entry_update(pte, (*(unsigned long *)pte)|_PAGE_RW);
-       if ( (unsigned long)va >= VMALLOC_START )
-               __make_page_writable(machine_to_virt(
-                       *(unsigned long *)pte&PAGE_MASK));
-}
-
-static inline void make_pages_readonly(void *va, unsigned int nr)
-{
-       while ( nr-- != 0 )
-       {
-               make_page_readonly(va);
-               va = (void *)((unsigned long)va + PAGE_SIZE);
-       }
-}
-
-static inline void make_pages_writable(void *va, unsigned int nr)
-{
-       while ( nr-- != 0 )
-       {
-               make_page_writable(va);
-               va = (void *)((unsigned long)va + PAGE_SIZE);
-       }
-}
+void make_lowmem_page_readonly(void *va);
+void make_lowmem_page_writable(void *va);
+void make_page_readonly(void *va);
+void make_page_writable(void *va);
+void make_pages_readonly(void *va, unsigned int nr);
+void make_pages_writable(void *va, unsigned int nr);
 
 static inline unsigned long arbitrary_virt_to_phys(void *va)
 {